"""管理员相关路由"""

from fastapi import APIRouter, HTTPException, Depends, BackgroundTasks
from pydantic import BaseModel
from typing import Dict, Any, List, Optional, Union
import logging
import time
import os

from backend.common.config import config_manager
from backend.logger_setup import get_logger_with_trace_id
from backend.middleware.trace_middleware import get_trace_id
from backend.middleware.auth_middleware import admin_required
from backend.database.db import DatabaseManager
from backend.llm import llm_manager
from backend.common.metrics import get_metrics

# 创建路由器
router = APIRouter(
    prefix=f"/{config_manager.api.version}/admin",
    tags=["管理"],
    responses={404: {"description": "未找到"}},
    dependencies=[Depends(admin_required)]  # 所有路由都需要管理员权限
)

logger = logging.getLogger('api.admin')

# 定义请求模型
class ConfigUpdateRequest(BaseModel):
    section: str
    key: str
    value: Any

class SystemInfoRequest(BaseModel):
    include_metrics: bool = True
    include_config: bool = False
    include_databases: bool = False

class RestartServiceRequest(BaseModel):
    components: List[str] = []  # 可选组件：['llm', 'rag', 'database', 'api']


@router.get("/health")
async def health_check(
    trace_id: str = Depends(get_trace_id)
):
    """系统健康检查"""
    # 获取带trace_id的logger
    log = get_logger_with_trace_id(logger, trace_id)
    log.info("执行系统健康检查")
    
    try:
        # 检查各组件健康状态
        components = {
            "api": {
                "status": "ok",
                "version": config_manager.api.version
            },
            "database": check_database_health(),
            "llm": check_llm_health(),
            "rag": check_rag_health(),
            "tools": check_tools_health()
        }
        
        # 确定总体健康状态
        overall_status = "ok"
        for component_name, component_status in components.items():
            if component_status.get("status") != "ok":
                overall_status = "degraded"
                break
        
        return {
            "status": overall_status,
            "components": components,
            "timestamp": time.time(),
            "trace_id": trace_id
        }
    except Exception as e:
        log.error(f"健康检查失败: {str(e)}")
        # 即使出错，健康检查接口本身也应该返回响应
        return {
            "status": "error",
            "error": str(e),
            "timestamp": time.time(),
            "trace_id": trace_id
        }


@router.get("/system-info")
async def get_system_info(
    request: Optional[SystemInfoRequest] = None,
    trace_id: str = Depends(get_trace_id)
):
    """获取系统信息"""
    # 获取带trace_id的logger
    log = get_logger_with_trace_id(logger, trace_id)
    log.info("获取系统信息")
    
    try:
        # 使用默认请求参数
        if request is None:
            request = SystemInfoRequest()
        
        # 构建系统信息
        system_info = {
            "environment": config_manager.environment,
            "version": config_manager.api.version,
            "python_version": get_python_version(),
            "timestamp": time.time(),
            "trace_id": trace_id
        }
        
        # 可选：包含指标信息
        if request.include_metrics:
            system_info["metrics"] = get_metrics()
        
        # 可选：包含配置信息（注意：敏感信息可能需要过滤）
        if request.include_config:
            system_info["config"] = get_sanitized_config()
        
        # 可选：包含数据库信息
        if request.include_databases:
            system_info["databases"] = get_database_info()
        
        return system_info
    except Exception as e:
        log.error(f"获取系统信息失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"Failed to get system info: {str(e)}")


@router.get("/config")
async def get_config(
    section: Optional[str] = None,
    trace_id: str = Depends(get_trace_id)
):
    """获取系统配置"""
    # 获取带trace_id的logger
    log = get_logger_with_trace_id(logger, trace_id)
    log.info(f"获取配置: section={section}")
    
    try:
        # 获取配置
        if section:
            # 获取特定部分的配置
            if hasattr(config_manager, section):
                config_section = getattr(config_manager, section)
                config_data = config_section.model_dump()
            else:
                raise HTTPException(status_code=404, detail=f"配置部分 '{section}' 不存在")
        else:
            # 获取所有配置（过滤敏感信息）
            config_data = get_sanitized_config()
        
        return {
            "config": config_data,
            "timestamp": time.time(),
            "trace_id": trace_id
        }
    except HTTPException:
        # 重新抛出HTTP异常
        raise
    except Exception as e:
        log.error(f"获取配置失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"Failed to get config: {str(e)}")


@router.post("/config")
async def update_config(
    request: ConfigUpdateRequest,
    trace_id: str = Depends(get_trace_id)
):
    """更新系统配置"""
    # 获取带trace_id的logger
    log = get_logger_with_trace_id(logger, trace_id)
    log.info(f"更新配置: section={request.section}, key={request.key}")
    
    try:
        # 检查配置部分是否存在
        if not hasattr(config_manager, request.section):
            raise HTTPException(status_code=404, detail=f"配置部分 '{request.section}' 不存在")
        
        # 获取配置部分
        config_section = getattr(config_manager, request.section)
        
        # 检查配置键是否存在
        if not hasattr(config_section, request.key):
            raise HTTPException(status_code=404, detail=f"配置键 '{request.key}' 不存在")
        
        # 更新配置
        # 注意：这里只更新运行时配置，不会持久化到配置文件
        # 如果需要持久化，需要实现配置文件写入逻辑
        setattr(config_section, request.key, request.value)
        
        log.info(f"配置已更新: {request.section}.{request.key} = {request.value}")
        
        return {
            "success": True,
            "message": f"配置 '{request.section}.{request.key}' 已更新",
            "section": request.section,
            "key": request.key,
            "value": request.value,
            "timestamp": time.time(),
            "trace_id": trace_id
        }
    except HTTPException:
        # 重新抛出HTTP异常
        raise
    except Exception as e:
        log.error(f"更新配置失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"Failed to update config: {str(e)}")


@router.post("/restart")
async def restart_services(
    request: Optional[RestartServiceRequest] = None,
    background_tasks: BackgroundTasks = BackgroundTasks(),
    trace_id: str = Depends(get_trace_id)
):
    """重启系统服务"""
    # 获取带trace_id的logger
    log = get_logger_with_trace_id(logger, trace_id)
    
    # 使用默认请求参数
    if request is None:
        request = RestartServiceRequest()
    
    log.info(f"重启服务: components={request.components}")
    
    try:
        # 生成任务ID
        task_id = f"restart_{trace_id[:8]}_{int(time.time())}"
        
        # 记录任务状态
        from backend.common.status_manager import status_manager
        status_manager.add_admin_status(task_id, {
            "status": "pending",
            "components": request.components,
            "trace_id": trace_id,
            "created_at": time.time()
        })
        
        # 添加后台任务
        background_tasks.add_task(
            restart_services_async,
            task_id, request.components
        )
        
        return {
            "task_id": task_id,
            "status": "pending",
            "message": "服务重启请求已提交，正在后台执行",
            "status_url": f"/{config_manager.api.version}/admin/status/{task_id}",
            "components": request.components,
            "trace_id": trace_id
        }
    except Exception as e:
        log.error(f"提交重启服务请求失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"Failed to submit restart request: {str(e)}")


@router.get("/status/{task_id}")
async def get_admin_task_status(
    task_id: str,
    trace_id: str = Depends(get_trace_id)
):
    """获取管理员任务状态"""
    # 获取带trace_id的logger
    log = get_logger_with_trace_id(logger, trace_id)
    log.info(f"获取管理员任务状态: task_id={task_id}")
    
    try:
        # 从状态管理器获取状态
        from backend.common.status_manager import status_manager
        status = status_manager.get_admin_status(task_id)
        
        if not status:
            raise HTTPException(status_code=404, detail=f"Task {task_id} not found")
        
        # 添加trace_id到返回结果
        status["trace_id"] = trace_id
        
        return status
    except HTTPException:
        # 重新抛出HTTP异常
        raise
    except Exception as e:
        log.error(f"获取管理员任务状态失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"Failed to get admin task status: {str(e)}")


@router.get("/logs")
async def get_logs(
    level: Optional[str] = None,
    component: Optional[str] = None,
    limit: int = 100,
    offset: int = 0,
    trace_id: str = Depends(get_trace_id)
):
    """获取系统日志"""
    # 获取带trace_id的logger
    log = get_logger_with_trace_id(logger, trace_id)
    log.info(f"获取日志: level={level}, component={component}, limit={limit}")
    
    try:
        # 这里应该实现日志获取逻辑
        # 由于当前没有日志管理系统，返回示例响应
        return {
            "logs": [],  # 实际应该返回日志条目列表
            "level": level,
            "component": component,
            "limit": limit,
            "offset": offset,
            "total": 0,  # 实际应该返回总日志数
            "trace_id": trace_id
        }
    except Exception as e:
        log.error(f"获取日志失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"Failed to get logs: {str(e)}")


# 辅助函数

def check_database_health():
    """检查数据库健康状态"""
    try:
        db_manager = DatabaseManager()
        conn = db_manager.get_connection()
        cursor = conn.cursor()
        cursor.execute("SELECT 1")
        cursor.fetchone()
        cursor.close()
        
        # 获取数据库统计信息
        stats = db_manager.get_stats()
        
        return {
            "status": "ok",
            "type": config_manager.database.type,
            "host": config_manager.database.host,
            "port": config_manager.database.port,
            "stats": stats
        }
    except Exception as e:
        return {
            "status": "error",
            "error": str(e)
        }

def check_llm_health():
    """检查LLM健康状态"""
    try:
        # 获取当前配置的LLM提供商
        provider_name = config_manager.llm.provider
        
        # 检查提供商是否可用
        available_providers = llm_manager.get_available_providers()
        
        return {
            "status": "ok" if provider_name in available_providers else "warning",
            "provider": provider_name,
            "model": config_manager.llm.model_name,
            "available_providers": available_providers
        }
    except Exception as e:
        return {
            "status": "error",
            "error": str(e)
        }

def check_rag_health():
    """检查RAG健康状态"""
    try:
        # 检查RAG相关配置
        from backend.rag.retriever import RAGRetriever
        retriever = RAGRetriever()
        
        # 检查检索器是否正常工作
        collections = retriever.list_collections()
        
        return {
            "status": "ok",
            "collections": collections,
            "collection_count": len(collections)
        }
    except Exception as e:
        return {
            "status": "error",
            "error": str(e)
        }

def check_tools_health():
    """检查工具健康状态"""
    try:
        from backend.tools.tool_registry import tool_registry
        
        # 获取已注册工具
        tools = tool_registry.get_registered_tools(show_details=False)
        
        # 计算可用工具数量
        available_count = sum(1 for tool in tools if tool["available"])
        
        return {
            "status": "ok",
            "tool_count": len(tools),
            "available_count": available_count
        }
    except Exception as e:
        return {
            "status": "error",
            "error": str(e)
        }

def get_python_version():
    """获取Python版本"""
    import sys
    return f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"

def get_sanitized_config():
    """获取清理后的配置（移除敏感信息）"""
    # 构建清理后的配置
    sanitized = {}
    
    # 遍历所有配置部分
    for section_name in dir(config_manager):
        # 跳过私有属性和方法
        if section_name.startswith('_') or callable(getattr(config_manager, section_name)):
            continue
        
        section = getattr(config_manager, section_name)
        
        # 处理不同类型的配置
        if hasattr(section, 'model_dump'):
            # Pydantic模型
            section_data = section.model_dump()
        else:
            section_data = dict(section)
        
        # 清理敏感信息
        section_sanitized = {}
        for key, value in section_data.items():
            # 检查是否包含敏感词
            if any(sensitive_key in key.lower() for sensitive_key in ['key', 'password', 'secret', 'token']):
                section_sanitized[key] = '********'
            else:
                section_sanitized[key] = value
        
        sanitized[section_name] = section_sanitized
    
    return sanitized

def get_database_info():
    """获取数据库信息"""
    db_manager = DatabaseManager()
    return db_manager.get_info()

async def restart_services_async(task_id: str, components: List[str]):
    """异步重启系统服务"""
    log = logging.getLogger('admin.restart')
    
    try:
        # 导入状态管理器
        from backend.common.status_manager import status_manager
        
        # 更新状态为执行中
        status_manager.update_admin_status(task_id, {
            "status": "running",
            "start_time": time.time()
        })
        
        # 记录重启组件
        restart_results = {}
        
        # 重启指定组件
        for component in components:
            try:
                if component == 'llm':
                    # 重启LLM服务
                    llm_manager.close_all()
                    restart_results[component] = "success"
                elif component == 'rag':
                    # 重启RAG服务
                    # 这里应该实现RAG服务重启逻辑
                    restart_results[component] = "success"
                elif component == 'database':
                    # 重启数据库连接
                    db_manager = DatabaseManager()
                    db_manager.close_all_connections()
                    db_manager.get_connection()  # 重新建立连接
                    restart_results[component] = "success"
                elif component == 'api':
                    # API重启通常需要外部干预，这里仅记录请求
                    restart_results[component] = "requested"
                else:
                    restart_results[component] = "unknown_component"
            except Exception as e:
                restart_results[component] = f"error: {str(e)}"
        
        # 更新状态为完成
        status_manager.update_admin_status(task_id, {
            "status": "completed",
            "results": restart_results,
            "end_time": time.time()
        })
        
        log.info(f"服务重启完成: task_id={task_id}, results={restart_results}")
    except Exception as e:
        error_message = str(e)
        log.error(f"服务重启失败: task_id={task_id}, error={error_message}")
        
        # 导入状态管理器
        from backend.common.status_manager import status_manager
        
        # 更新状态为失败
        status_manager.update_admin_status(task_id, {
            "status": "failed",
            "error": error_message,
            "end_time": time.time()
        })